/**
 * 
 */
package com.yi.model.internal.impl;

import java.util.LinkedHashMap;
import java.util.Map;
import com.mongodb.BasicDBObject;

import com.yi.model.db.mongo.MongoDBHelper;
import com.yi.model.internal.IModelUIConfigApi;
import com.yi.model.objects.DBDefinitions;
import com.yi.model.objects.Field;
import com.yi.model.objects.HtmlTypes;
import com.yi.model.objects.ModelUIConfig;
import com.yi.model.objects.ModelTypes;
import com.yi.model.objects.TableTypes;
import com.yi.role.internal.IRoleApi;
import com.yi.role.objects.Role;
import com.yi.user.internal.IUserApi;
import com.yi.user.objects.User;

/**
 * @author yilo
 *
 */
public class ModelInitializer {
	private MongoDBHelper dbHelper;
	private IRoleApi roleApi;
	private IUserApi userApi;
	private IModelUIConfigApi modelUIConfigApi;
	
	private void createDefaultCollections(){
		//create basic collections
		dbHelper.createCollectionByName(DBDefinitions.roleColl);
		dbHelper.createCollectionByName(DBDefinitions.modelUIConfigsColl);
		dbHelper.createCollectionByName(DBDefinitions.userColl);
	}
	
	/**
	 * generate basic collections in mongo db
	 */
	public void initialize(){
		
		createDefaultCollections();
		
		Map<String,Object> defaultFields = new LinkedHashMap<String,Object>();
		//id
		BasicDBObject idConfig = new BasicDBObject();
		idConfig.put(Field.htmlType, HtmlTypes.chbox);
		idConfig.put(Field.tableType, TableTypes.chx);
		idConfig.put(Field.isSearch, false);
		idConfig.put(Field.name, "id");
		defaultFields.put("id", idConfig);
		//name
		BasicDBObject nameConfig = new BasicDBObject();
		nameConfig.put(Field.htmlType, HtmlTypes.smallText);
		nameConfig.put(Field.tableType, TableTypes.uptxt);
		nameConfig.put(Field.isSearch, true);
		nameConfig.put(Field.name, DBDefinitions.col_name);
		defaultFields.put(DBDefinitions.col_name, nameConfig);
		//desc
		BasicDBObject descConfig = new BasicDBObject();
		descConfig.put(Field.htmlType, HtmlTypes.bigText);
		descConfig.put(Field.tableType, TableTypes.uptxt);
		descConfig.put(Field.isSearch, false);
		descConfig.put(Field.name, DBDefinitions.col_desc);
		defaultFields.put(DBDefinitions.col_desc, descConfig);
		//created
		BasicDBObject createdConfig = new BasicDBObject();
		createdConfig.put(Field.htmlType, HtmlTypes.dateTime);
		createdConfig.put(Field.tableType, TableTypes.uptxt);
		createdConfig.put(Field.isSearch, true);
		createdConfig.put(Field.name, DBDefinitions.col_created);
		defaultFields.put(DBDefinitions.col_created, createdConfig);
		//updated
		BasicDBObject updatedConfig = new BasicDBObject();
		updatedConfig.put(Field.htmlType, HtmlTypes.dateTime);
		updatedConfig.put(Field.tableType, TableTypes.hidden);
		updatedConfig.put(Field.isSearch, true);
		updatedConfig.put(Field.name, DBDefinitions.col_updated);
		defaultFields.put(DBDefinitions.col_updated, updatedConfig);

		//create modeltypes
		ModelUIConfig mtmodelType = new ModelUIConfig();
		mtmodelType.name = "modelTypes";
		mtmodelType.desc = "define model type and generate name+coll table in mongo";
		mtmodelType.type = ModelTypes.spec;
		Map<String,Object> mtFields = new LinkedHashMap<String,Object>(defaultFields);
		BasicDBObject typeConfig = new BasicDBObject();
		typeConfig.put(Field.htmlType, HtmlTypes.smallText);
		typeConfig.put(Field.tableType, TableTypes.hidden);
		typeConfig.put(Field.isSearch, true);
		typeConfig.put(Field.name, DBDefinitions.col_type);
		
		mtFields.put(DBDefinitions.col_type, typeConfig);
		mtmodelType.fields = mtFields;		
		String mtModelTypeId = getModelUIConfigApi().create(mtmodelType);
		
		ModelUIConfig rolemodelType = new ModelUIConfig();
		rolemodelType.name = "roles";
		rolemodelType.desc = "authentication & authorization info";
		rolemodelType.type = ModelTypes.meta;
		//
		Map<String,Object> roleFields = new LinkedHashMap<String,Object>(defaultFields);
		BasicDBObject permissonConfig = new BasicDBObject();
		permissonConfig.put(Field.htmlType, HtmlTypes.tree);
		permissonConfig.put(Field.tableType, TableTypes.hidden);
		permissonConfig.put(Field.isSearch, false);
		permissonConfig.put(Field.name, DBDefinitions.col_permission);
		
		roleFields.put(DBDefinitions.col_permission, permissonConfig);
		
		rolemodelType.fields = roleFields;
		String roleModelTypeId = getModelUIConfigApi().create(rolemodelType);
				
		
		ModelUIConfig usermodelType = new ModelUIConfig();
		usermodelType.name = "users";
		usermodelType.desc = "authentication & authorization info";
		usermodelType.type = ModelTypes.meta;
		Map<String,Object> userFields = new LinkedHashMap<String,Object>(defaultFields);
		BasicDBObject emailConfig = new BasicDBObject();
		emailConfig.put(Field.htmlType, HtmlTypes.smallText);
		emailConfig.put(Field.tableType, TableTypes.uptxt);
		emailConfig.put(Field.isSearch, true);
		emailConfig.put(Field.name, DBDefinitions.col_email);
		
		userFields.put(DBDefinitions.col_email, emailConfig);
		
		BasicDBObject roleIdConfig = new BasicDBObject();
		roleIdConfig.put(Field.htmlType, HtmlTypes.others);
		roleIdConfig.put(Field.tableType, TableTypes.hidden);
		roleIdConfig.put(Field.isSearch, false);
		roleIdConfig.put(Field.name, DBDefinitions.col_roleId);
		
		userFields.put(DBDefinitions.col_roleId, roleIdConfig);
		
		BasicDBObject roleNameConfig = new BasicDBObject();
		roleNameConfig.put(Field.htmlType, HtmlTypes.others);
		roleNameConfig.put(Field.tableType, TableTypes.uptxt);
		roleNameConfig.put(Field.isSearch, true);
		roleNameConfig.put(Field.name, DBDefinitions.col_roleName);
		
		userFields.put(DBDefinitions.col_roleName, roleNameConfig);
		
		usermodelType.fields = userFields;
		String userModelTypeId = getModelUIConfigApi().create(usermodelType);
		
		//create default users & roles & permission
		Role adminRole = new Role();
		adminRole.name = "admins";
		adminRole.desc = "handle everything";
		adminRole.modelTypeId = roleModelTypeId;
		Map<String,String> perms = new LinkedHashMap<String,String>();
		perms.put("*", "*");
		adminRole.permissions = perms;		
		String adminRoleId = roleApi.create(adminRole);
		
		User admin = new User();
		admin.name = "admin";
		admin.desc = "handle everything";
		admin.email = "long.yi@autodesk.com";
		admin.roleId = adminRoleId;
		admin.roleName = adminRole.name;
		admin.modelTypeId = userModelTypeId;		
		userApi.create(admin);
		
		Role guestRole = new Role();
		guestRole.name = "guests";
		guestRole.desc = "view everything";
		guestRole.modelTypeId = roleModelTypeId;
		perms = new LinkedHashMap<String,String>();
		perms.put("*", "view,list");
		guestRole.permissions = perms;
		
		String guestRoleId = roleApi.create(guestRole);
		
		User guest = new User();
		guest.name = "guest";
		guest.desc = "view & list everything";
		guest.email = "long.yi@autodesk.com";
		guest.roleId = guestRoleId;
		guest.roleName = guestRole.name;
		guest.modelTypeId = userModelTypeId;
		
		userApi.create(guest);
		
	}
	public MongoDBHelper getDbHelper() {
		return dbHelper;
	}
	public void setDbHelper(MongoDBHelper dbHelper) {
		this.dbHelper = dbHelper;
	}
	public IRoleApi getRoleApi() {
		return roleApi;
	}
	public void setRoleApi(IRoleApi roleApi) {
		this.roleApi = roleApi;
	}
	public IUserApi getUserApi() {
		return userApi;
	}
	public void setUserApi(IUserApi userApi) {
		this.userApi = userApi;
	}
	public IModelUIConfigApi getModelUIConfigApi() {
		return modelUIConfigApi;
	}
	public void setModelUIConfigApi(IModelUIConfigApi modelUIConfigApi) {
		this.modelUIConfigApi = modelUIConfigApi;
	}

}
